﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace PasswordEnumerator
{
    public class PEData
    {
        /// <summary>
        /// 组合 下标
        /// </summary>
        public  int[] WordsIndexs { get; set; }
        /// <summary>
        /// 所有的项
        /// </summary>
        public  string[] Words { get; set; }
        /// <summary>
        /// 起始项
        /// </summary>
        public  string StartWords { get; set; }
        /// <summary>
        /// 结束项
        /// </summary>
        public  string EndWords { get; set; }
        /// <summary>
        /// 开始时间
        /// </summary>
        public DateTime BeginTime { get; set; }
        /// <summary>
        /// 结束时间
        /// </summary>
        public DateTime EndTime { get; set; }

        /// <summary>
        /// 最后一项
        /// </summary>
        public string TheLastPEWords { get; set; }
        /// <summary>
        /// 是否找到密码
        /// </summary>
        public  bool IsFound { get; set; }

        /// <summary>
        /// 是否结束循环
        /// </summary>
        public bool IsEndLoop { get; set; }

        /// <summary>
        /// 日志记录事件
        /// </summary>
        public  event LogCallback logEvent;
        /// <summary>
        /// 自定义最小长度
        /// 0 代表 1
        /// 1 代表2 ...
        /// </summary>
        private int selfMinLength;

        /// <summary>
        /// 自定义最小长度
        /// 0 代表 1
        /// 1 代表2 ...
        /// </summary>
        public int SelfMinLength
        {
            get { return selfMinLength; }
            set
            {
                if (value-1 < 0)
                {
                    selfMinLength = 0;
                }
                else
                {
                    selfMinLength = value-1;
                }
            }
        }
        /// <summary>
        /// 序号
        /// </summary>
        public int Sequence { get; set; }
        /// <summary>
        /// 当前 长度
        ///  0 代表 1
        /// 1 代表2 ...
        /// </summary>
        private int currentLength;
        /// <summary>
        /// 当前 长度
        ///  0 代表 1
        /// 1 代表2 ...
        /// </summary>
        public int CurrentLength
        {
            get { return currentLength; }

            set
            {
                currentLength = value;
            }
        }

        /// <summary>
        /// 自定义最大长度
        /// 0 代表 1
        /// 1 代表2 ..
        /// </summary>
        private int selfMaxLength;
        /// <summary>
        /// 自定义最大长度
        /// 0 代表 1
        /// 1 代表2 ..
        /// </summary>
        public int SelfMaxLength
        {
            get { return selfMaxLength; }
            set
            {
                if (value-1 > maxLength)
                {
                    this.selfMaxLength = maxLength;
                }
                else
                {
                    this.selfMaxLength = value-1;
                }
            }
        }

        // event LogCallback
        /// <summary>
        /// 最大长度 63
        /// </summary>
        private const int maxLength = 63;

        public int MaxLength
        {
            get { return maxLength; }
        } 

        public void Init()
        {
            this.StartWords = "";
            this.EndWords = "";
            this.IsFound = false;
            this.IsEndLoop = false;
            this.SelfMinLength = 0;
            Sequence = 0;
            this.CurrentLength = SelfMinLength;
            this.SelfMaxLength = maxLength;
        }

        /// <summary>
        /// 初始化数组 初始值为 -1
        /// </summary>
        /// <param name="array"></param>
        public static void InitIntArray(int[] array,int selfMinLength,int currentLength, int wordsLength)
        {
            if (array.Length==0)
            {
                return;
            }
            for (int i = 0; i < array.Length; i++)
            {
                if (i <= currentLength && currentLength != 0)
                {
                    array[i] = wordsLength - 1;
                }
                else
                {
                    array[i] = -1;
                }
            }
            if (selfMinLength == 1)
            {
                array[0] = wordsLength - 1;
            }
        }

        /// <summary>
        /// 生成下一密码
        /// </summary>
        /// <returns></returns>
        public string GetPasswrd()
        {
            
            lock (this)
            {
                
                Sequence++;
                if (Sequence % 10000000 == 0)
                {
                    if (logEvent!=null)
                    {
                        logEvent();
                    }
                   
                }
                this.WordsIndexs[0]++;
                this.UpGrade(0);
                if (this.IsEndLoop)
                {
                    return "";
                }
                StringBuilder sb = new StringBuilder(this.CurrentLength + this.StartWords.Length + this.EndWords.Length);
                sb.Append(this.StartWords);
                for (int i = this.CurrentLength; i >= 0; i--)
                {
                    sb.Append(this.Words[this.WordsIndexs[i]]);
                }
                sb.Append(this.EndWords);
                return this.TheLastPEWords= sb.ToString();
            }
             
        }

        /// <summary>
        /// 下标 进位
        /// </summary>
        /// <param name="i"></param>
        private  void UpGrade(int i)
        {
            if (this.WordsIndexs[i]==26)
            {
                
            }
            if ((this.WordsIndexs[i] >= this.Words.Length) && i < this.SelfMaxLength+1)
            {
                this.WordsIndexs[i] = 0;
                this.WordsIndexs[i + 1]++;
                if (this.WordsIndexs[i + 1] == 0)
                {
                    this.CurrentLength += 1;
                    if (this.CurrentLength > this.SelfMaxLength)
                    {
                        this.IsEndLoop = true;
                    }
                    if (logEvent!=null)
                    {
                        logEvent();
                    }
                    
                }
                this.UpGrade(i + 1);
            }
        }

        
    }
}
